package com.jmag.nop.service.common.util;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.FatalBeanException;
import org.springframework.util.Assert;
/**
 * @ClassName CopyUtil
 * @Description TODO
 * @Author JMAG
 * @Version 1.0
 **/
public class CopyUtil extends BeanUtils {
    public CopyUtil() {
    }

    public static void copyProperties(Map<String, Object> map, Object target) {
        Assert.notNull(map, "map must not be null");
        Assert.notNull(target, "Target must not be null");
        if (target instanceof Map) {
            Map targetMap = (Map)target;

            try {
                targetMap.putAll(map);
            } catch (Exception var18) {
                throw new FatalBeanException("target的key类型必须为String，value类型为Object");
            }
        } else {
            Set<Entry<String, Object>> entrySet = map.entrySet();
            Class<?> targetClass = target.getClass();
            Iterator var4 = entrySet.iterator();

            while(var4.hasNext()) {
                Entry<String, Object> entry = (Entry)var4.next();
                String propertyName = (String)entry.getKey();
                Object val = entry.getValue();
                Method[] methods = targetClass.getDeclaredMethods();
                Method[] var9 = methods;
                int var10 = methods.length;

                for(int var11 = 0; var11 < var10; ++var11) {
                    Method method = var9[var11];
                    String methodName = method.getName();
                    Class<?>[] methodParams = method.getParameterTypes();
                    if (methodName.startsWith("set")) {
                        boolean canCopy = propertyName.equals(ReflectionUtil.buildFieldName(methodName)) && methodParams.length == 1 && methodParams[0].isInstance(val) || Number.class.isInstance(val);
                        if (canCopy) {
                            try {
                                if (!Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
                                    method.setAccessible(true);
                                }

                                method.invoke(target, val);
                            } catch (Throwable var17) {
                                throw new FatalBeanException("Could not copy property '" + propertyName + "' from map to target", var17);
                            }
                        }
                    }
                }
            }
        }

    }

    public static void copyPropertiesIgnoreNull(Object source, Object target) throws BeansException {
        Assert.notNull(source, "Source must not be null");
        Assert.notNull(target, "Target must not be null");
        Class<?> actualEditable = target.getClass();
        PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
        PropertyDescriptor[] var4 = targetPds;
        int var5 = targetPds.length;

        for(int var6 = 0; var6 < var5; ++var6) {
            PropertyDescriptor targetPd = var4[var6];
            Method writeMethod = targetPd.getWriteMethod();
            if (writeMethod != null) {
                PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
                if (sourcePd != null && sourcePd.getReadMethod() != null) {
                    try {
                        Method readMethod = sourcePd.getReadMethod();
                        if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
                            readMethod.setAccessible(true);
                        }

                        Object value = readMethod.invoke(source);
                        if (value != null) {
                            if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
                                writeMethod.setAccessible(true);
                            }

                            writeMethod.invoke(target, value);
                        }
                    } catch (Throwable var12) {
                        throw new FatalBeanException("Could not copy properties from source to target field name mismatch:" + targetPd.getName(), var12);
                    }
                }
            }
        }

    }
}
